001 /*
002 * Copyright 2005 Stephen J. McConnell
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.library.info;
020
021 import java.io.OutputStream;
022 import java.io.IOException;
023 import java.io.Writer;
024 import java.io.OutputStreamWriter;
025 import java.util.Properties;
026
027 import net.dpml.lang.Category;
028 import net.dpml.lang.Version;
029
030 import net.dpml.library.info.IncludeDirective.Mode;
031
032
033 /**
034 * Utility class used for construction of a module model from an XML source.
035 *
036 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
037 * @version 1.1.0
038 */
039 public final class LibraryEncoder extends LibraryConstants
040 {
041 /**
042 * Write a module directive to an output stream as a portable XML definition.
043 * During export dependencies are limited to runtime concerns (eliminating
044 * build and test scoped dependencies). Artifact production is strippped down
045 * to a generic type declaration. The resulting XML file is suitable for
046 * publication and usage by external projects.
047 *
048 * @param module the module directive to externalize
049 * @param output the output stream
050 * @exception IOException if an error occurs during module externalization
051 */
052 public void export( final ModuleDirective module, final OutputStream output ) throws IOException
053 {
054 final Writer writer = new OutputStreamWriter( output );
055 try
056 {
057 writer.write( XML_HEADER );
058 writer.write( "\n" );
059
060 String name = module.getName();
061 String version = module.getVersion();
062
063 if( null != name )
064 {
065 writer.write( "<module name=\"" + name + "\"" );
066 }
067 if( null != version )
068 {
069 writer.write( " version=\"" + version + "\"" );
070 }
071
072 writer.write(
073 "\n xmlns=\""
074 + MODULE_XSD_URI
075 + "\">" );
076
077 String basedir = module.getBasedir();
078 InfoDirective info = module.getInfoDirective();
079 Properties properties = module.getProperties();
080 TypeDirective[] types = module.getTypeDirectives();
081 DependencyDirective[] dependencies = module.getDependencyDirectives();
082 ResourceDirective[] resources = module.getResourceDirectives();
083
084 if( !info.isNull() )
085 {
086 writer.write( "\n" );
087 writeInfo( writer, info, " " );
088 }
089 if( properties.size() > 0 )
090 {
091 writer.write( "\n" );
092 writeProperties( writer, properties, " ", true );
093 }
094 if( types.length > 0 )
095 {
096 writer.write( "\n" );
097 writeTypes( writer, types, " " );
098 }
099 if( dependencies.length > 0 )
100 {
101 writer.write( "\n" );
102 writeDependencies( writer, dependencies, " " );
103 }
104 if( resources.length > 0 )
105 {
106 writeResources( writer, resources, " " );
107 }
108 writer.write( "\n\n</module>" );
109 writer.write( "\n" );
110 }
111 finally
112 {
113 writer.flush();
114 writer.close();
115 }
116 }
117
118 private void writeModule( Writer writer, ModuleDirective module, String lead ) throws IOException
119 {
120 String name = module.getName();
121 String version = module.getVersion();
122
123 InfoDirective info = module.getInfoDirective();
124 Properties properties = module.getProperties();
125 String basedir = module.getBasedir();
126 TypeDirective[] types = module.getTypeDirectives();
127 DependencyDirective[] dependencies = module.getDependencyDirectives();
128 ResourceDirective[] resources = module.getResourceDirectives();
129
130 writer.write( "\n" + lead + "<module" );
131 if( null != name )
132 {
133 writer.write( " name=\"" + name + "\"" );
134 }
135 if( null != version )
136 {
137 writer.write( " version=\"" + version + "\"" );
138 }
139 writer.write( ">" );
140
141 if( !info.isNull() )
142 {
143 writer.write( "\n" );
144 writeInfo( writer, info, lead + " " );
145 }
146 if( properties.size() > 0 )
147 {
148 writer.write( "\n" );
149 writeProperties( writer, properties, lead + " ", true );
150 }
151
152 if( types.length > 0 )
153 {
154 writer.write( "\n" );
155 writeTypes( writer, types, lead + " " );
156 }
157
158 if( dependencies.length > 0 )
159 {
160 writer.write( "\n" );
161 writeDependencies( writer, dependencies, lead + " " );
162 }
163
164 if( resources.length > 0 )
165 {
166 writeResources( writer, resources, lead + " " );
167 }
168 writer.write( "\n\n" + lead + "</module>" );
169 }
170
171 private void writeResource( Writer writer, ResourceDirective resource, String lead ) throws IOException
172 {
173 String name = resource.getName();
174 String version = resource.getVersion();
175
176 InfoDirective info = resource.getInfoDirective();
177 Properties properties = resource.getProperties();
178 String basedir = resource.getBasedir();
179 TypeDirective[] types = resource.getTypeDirectives();
180 DependencyDirective[] dependencies = resource.getDependencyDirectives();
181
182 writer.write( "\n" + lead + "<resource" );
183 if( null != name )
184 {
185 writer.write( " name=\"" + name + "\"" );
186 }
187 if( null != version )
188 {
189 writer.write( " version=\"" + version + "\"" );
190 }
191 writer.write( ">" );
192
193 if( !info.isNull() )
194 {
195 writer.write( "\n" );
196 writeInfo( writer, info, lead + " " );
197 }
198 if( properties.size() > 0 )
199 {
200 writeProperties( writer, properties, lead + " ", true );
201 }
202 if( types.length > 0 )
203 {
204 writeTypes( writer, types, lead + " " );
205 }
206 if( dependencies.length > 0 )
207 {
208 writeDependencies( writer, dependencies, lead + " " );
209 }
210 writer.write( "\n" + lead + "</resource>" );
211 }
212
213 private void writeInfo(
214 Writer writer, InfoDirective info, String lead ) throws IOException
215 {
216 writer.write( lead + "<info" );
217 if( null != info.getTitle() )
218 {
219 writer.write( " title=\"" + info.getTitle() + "\"" );
220 }
221 String description = info.getDescription();
222 if( null != description )
223 {
224 writer.write( ">" );
225 writer.write( "\n" + lead + " <description>" );
226 writer.write( "\n" + lead + " " + description );
227 writer.write( "\n" + lead + " </description>" );
228 writer.write( "\n" + lead + "</info>" );
229 }
230 else
231 {
232 writer.write( "/>" );
233 }
234 }
235
236 private void writeProperties(
237 Writer writer, Properties properties, String lead, boolean flag ) throws IOException
238 {
239 if( properties.size() > 0 )
240 {
241 if( flag )
242 {
243 writer.write( "\n" + lead + "<properties>" );
244 }
245 String[] names = (String[]) properties.keySet().toArray( new String[0] );
246 for( int i=0; i<names.length; i++ )
247 {
248 String name = names[i];
249 String value = properties.getProperty( name );
250 writer.write( "\n" + lead );
251 if( flag )
252 {
253 writer.write( " " );
254 }
255 writer.write( "<property name=\"" + name + "\" value=\"" + value + "\"/>" );
256 }
257 if( flag )
258 {
259 writer.write( "\n" + lead + "</properties>" );
260 }
261 }
262 }
263
264 private void writeTypes( Writer writer, TypeDirective[] types, String lead ) throws IOException
265 {
266 if( types.length > 0 )
267 {
268 writer.write( "\n" + lead + "<types>" );
269 for( int i=0; i<types.length; i++ )
270 {
271 TypeDirective type = types[i];
272 writeType( writer, type, lead + " " );
273 }
274 writer.write( "\n" + lead + "</types>" );
275 }
276 }
277
278 private void writeType( Writer writer, TypeDirective type, String lead ) throws IOException
279 {
280 String id = type.getID();
281 writer.write( "\n" + lead + "<type id=\"" + id + "\"" );
282 Version version = type.getVersion();
283 if( null != version )
284 {
285 if( Version.NULL_VERSION.equals( version ) )
286 {
287 writer.write( " alias=\"true\"" );
288 }
289 else
290 {
291 writer.write( " version=\"" + version.getMajor() + "." + version.getMinor() + "\"" );
292 }
293 }
294 writer.write( "/>" );
295 }
296
297 private void writeDependencies(
298 Writer writer, DependencyDirective[] dependencies, String lead ) throws IOException
299 {
300 if( dependencies.length > 0 )
301 {
302 writer.write( "\n" + lead + "<dependencies>" );
303
304 for( int i=0; i<dependencies.length; i++ )
305 {
306 DependencyDirective dependency = dependencies[i];
307 IncludeDirective[] includes = dependency.getIncludeDirectives();
308 if( includes.length > 0 )
309 {
310 Scope scope = dependency.getScope();
311 String label = scope.toString().toLowerCase();
312 writer.write( "\n" + lead + " <" + label + ">" );
313 for( int j=0; j<includes.length; j++ )
314 {
315 IncludeDirective include = includes[j];
316 Mode mode = include.getMode();
317 String value = include.getValue();
318 writer.write( "\n" + lead + " <include" );
319 if( Mode.KEY.equals( mode ) )
320 {
321 writer.write( " key=\"" + value + "\"" );
322 }
323 else if( Mode.REF.equals( mode ) )
324 {
325 writer.write( " ref=\"" + value + "\"" );
326 }
327 else if( Mode.URI.equals( mode ) )
328 {
329 writer.write( " uri=\"" + value + "\"" );
330 }
331
332 if( Scope.RUNTIME.equals( scope ) )
333 {
334 Category category = include.getCategory();
335 if( !Category.PRIVATE.equals( category ) )
336 {
337 String name = category.getName().toLowerCase();
338 writer.write( " tag=\"" + name + "\"" );
339 }
340 }
341
342 Properties props = include.getProperties();
343 if( props.size() > 0 )
344 {
345 writer.write( ">" );
346 writeProperties( writer, props, lead + " ", false );
347 writer.write( "\n" + lead + " </include>" );
348 }
349 else
350 {
351 writer.write( "/>" );
352 }
353 }
354 writer.write( "\n" + lead + " </" + label + ">" );
355 }
356 }
357 writer.write( "\n" + lead + "</dependencies>" );
358 }
359 }
360
361 private void writeResources( Writer writer, ResourceDirective[] resources, String lead ) throws IOException
362 {
363 for( int i=0; i<resources.length; i++ )
364 {
365 ResourceDirective resource = resources[i];
366 if( resource instanceof ModuleDirective )
367 {
368 writer.write( "\n" );
369 ModuleDirective module = (ModuleDirective) resource;
370 writeModule( writer, module, lead );
371 }
372 else
373 {
374 writer.write( "\n" );
375 writeResource( writer, resource, lead );
376 }
377 }
378 }
379 }